// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#pragma once

#include <map>
#include <memory>
#include <string>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/kraken/api_util/auth_key.h"
#include "coin2/exchange/order/kraken.pb.h"

class KrakenRateTracker;

class KrakenNativePrivateClient : public coin2::exchange::base::order::NativePrivateClient {
 public:
  using RestParams = coin2::exchange::order::KrakenRestParams;
  using NativeClientConfig = coin2::exchange::order::OrderConnectionConfig;
  using ActionType = coin2::exchange::base::order::NativePrivateClient::ActionType;

 public:
  std::shared_ptr<AsioHttpContext> SubmitOrderExecution(const OrderExecutionProto& order);
  std::shared_ptr<AsioHttpContext> SubmitRestQuery(const RestQueryProto& query);

 public:
  explicit KrakenNativePrivateClient(
      const MarketExchangeApi& mea,
      const NativeClientConfig& config);

  void Prepare() override;

  std::shared_ptr<AsioHttpContext> QueryAccountBalance();
  std::shared_ptr<AsioHttpContext> QueryOpenOrders();
  std::shared_ptr<AsioHttpContext> QueryClosedOrders();
  std::shared_ptr<AsioHttpContext> QueryTrades();
  std::shared_ptr<AsioHttpContext> PlaceOrder(const RestParams& params);
  std::shared_ptr<AsioHttpContext> CancelOrder(const RestParams& params);
  std::shared_ptr<AsioHttpContext> CancelOrder(const RestParams& params, int64_t order_created_ts);
  std::shared_ptr<AsioHttpContext> GetWsToken();

  std::shared_ptr<AsioHttpContext> PlaceOrderNorm(const OrderExecution&) override;
  std::shared_ptr<AsioHttpContext> CancelOrderNorm(const OrderExecution&) override;

  RestParams GetRestOrderParams(const OrderSpec& order_spec, int64_t proc_order_id);
  RestParams GetRestCancelParams(const IOrderContext& order_context);

  bool HasEnoughRateLimit(int64_t ts, ActionType action_type, const std::string& symbol) const;
  void Push(int32_t num_reqs, int64_t ts, ActionType action_type, const std::string& symbol);

 private:
  auto GetCancelOrderRateLimitWeight(int64_t timestamp, int64_t order_created_ts) const -> int;

 private:
  KrakenRateTracker* local_rate_tracker_;
};
